﻿using Common.Communal;
using ERP.Domain.CustomerSupplier;
using MediatR;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Warehouse.API.Read.App.Commands;
using Warehouse.Dto;
using ERP.Domain.Warehouse;
using Microsoft.AspNetCore.SignalR;
using Warehouse.API.Read.Hubs;
using Warehouse.API.Read.HubClients;

namespace Warehouse.API.Read.Controllers
{
    /// <summary>
    /// 报表汇总控制器 - 提供库存数据的查询和汇总功能
    /// 实现 RESTful API 接口，支持分页查询、条件筛选等功能
    /// 采用 CQRS 模式，通过 MediatR 处理查询请求
    /// </summary>
    [Route("api/[controller]/[action]")]  // 路由模板：api/ReportSummary/{action}
    [ApiController]                       // 启用 API 控制器特性
    public class ReportSummaryController : ControllerBase
    {
        #region 私有字段

        /// <summary>
        /// MediatR 中介者 - 实现命令查询分离模式
        /// 负责将请求路由到对应的处理器，实现松耦合架构
        /// </summary>
        private readonly IMediator _mediator;
        ILogger<ReportSummaryController> logger;
        private readonly IHubContext<ChatHub, IChatClient> _hubContext;

        #endregion

        #region 构造函数

        /// <summary>
        /// 构造函数 - 依赖注入初始化
        /// </summary>
        /// <param name="mediator">MediatR 中介者实例</param>
        public ReportSummaryController(IMediator mediator, IHubContext<ChatHub, IChatClient> hubContext, ILogger<ReportSummaryController> logger)
        {
            _mediator = mediator;
            _hubContext = hubContext;
            this.logger = logger;
        }

        #endregion

        #region 公共 API 方法

        /// <summary>
        /// 获取供应商汇总列表 - 库存数据的汇总统计查询
        /// 按产品名称分组，计算入库、出库和结余数量
        /// </summary>
        /// <param name="request">查询请求参数 - 包含分页信息和查询条件</param>
        /// <returns>分页的汇总数据列表</returns>
        /// <remarks>
        /// 示例请求：
        /// GET /api/ReportSummary/Supplierlist?pageindex=1&pagesize=10&ProductName=电机
        /// 
        /// 响应格式：
        /// {
        ///   "code": 200,
        ///   "message": "查询成功",
        ///   "data": {
        ///     "totalCount": 100,
        ///     "totalPage": 10,
        ///     "data": [
        ///       {
        ///         "productName": "电机",
        ///         "inQuantity": 100,
        ///         "outQuantity": 50,
        ///         "balanceQuantity": 50
        ///       }
        ///     ]
        ///   }
        /// }
        /// </remarks>
        [HttpGet]  // HTTP GET 方法
        [ProducesResponseType(typeof(ApiResult<ApiPaging<InventorySummaryDto>>), 200)]  // 成功响应类型
        [ProducesResponseType(typeof(ApiResult<ApiPaging<InventorySummaryDto>>), 400)]  // 错误响应类型
        public async Task<ApiResult<ApiPaging<InventorySummaryDto>>> Supplierlist([FromQuery] ReportSummary request)
        {
            try
            {
                // 通过 MediatR 发送查询请求
                // 这会自动路由到 ReportSummaryHanders 处理器进行处理
                logger.LogInformation("显示成功");
                var result = await _mediator.Send(request);
                
                return result;
            }
            catch (Exception ex)
            {
                // 异常处理 - 返回统一的错误响应格式
                return new ApiResult<ApiPaging<InventorySummaryDto>>
                {
                    Code = EnumCode.Fail,
                    Message = $"查询失败: {ex.Message}",
                    Data = null
                };
            }
        }

        /// <summary>
        /// 获取库存交易记录列表 - 按产品名称查询库存交易明细
        /// 提供详细的库存交易记录，支持分页和条件筛选
        /// </summary>
        /// <param name="request">查询请求参数 - 包含分页信息和产品名称筛选条件</param>
        /// <returns>分页的库存交易记录列表</returns>
        /// <remarks>
        /// 示例请求：
        /// GET /api/ReportSummary/InventoryTransactions?pageindex=1&pagesize=10&ProductName=电机
        /// 
        /// 响应格式：
        /// {
        ///   "code": 200,
        ///   "message": "查询成功",
        ///   "data": {
        ///     "totalCount": 50,
        ///     "totalPage": 5,
        ///     "data": [
        ///       {
        ///         "id": 1,
        ///         "productName": "电机",
        ///         "transactionType": "入库",
        ///         "quantity": 100,
        ///         "transactionTime": "2024-01-01T10:00:00"
        ///       }
        ///     ]
        ///   }
        /// }
        /// </remarks>
        [HttpGet]  // HTTP GET 方法
        [ProducesResponseType(typeof(ApiResult<ApiPaging<InventoryTransaction>>), 200)]  // 成功响应类型
        [ProducesResponseType(typeof(ApiResult<ApiPaging<InventoryTransaction>>), 400)]  // 错误响应类型
        public async Task<ApiResult<ApiPaging<InventoryTransaction>>> InventoryTransactions([FromQuery] InventoryTransactionList request)
        {
            try
            {
                // 通过 MediatR 发送查询请求
                // 这会自动路由到 InventoryTransactionListHandler 处理器进行处理
                var result = await _mediator.Send(request);
                
                return result;
            }
            catch (Exception ex)
            {
                // 异常处理 - 返回统一的错误响应格式
                return new ApiResult<ApiPaging<InventoryTransaction>>
                {
                    Code = EnumCode.Fail,
                    Message = $"查询失败: {ex.Message}",
                    Data = null
                };
            }
        }

        /// <summary>
        /// 通知前端库存数据已变化（由写服务在新增/修改/删除后调用）
        /// 将根据传入的查询条件重新汇总并通过 SignalR 推送到所有在线客户端
        /// </summary>
        /// <param name="request">汇总查询条件（仅 ProductName + 分页）</param>
        /// <returns>推送的同款数据，便于调用方观察</returns>
        [HttpPost]
        public async Task<ApiResult<ApiPaging<InventorySummaryDto>>> NotifyInventoryChanged([FromBody] ReportSummary request)
        {
            // 1) 查询最新的汇总结果
            var result = await _mediator.Send(request);

            // 2) 通过 SignalR 广播给所有客户端（与 ChatHub 的客户端契约一致）
            await _hubContext.Clients.All.SendMessage(result);

            // 3) 返回查询结果给调用方（可选）
            return result;
        }

        #endregion

        #region 私有辅助方法

        /// <summary>
        /// 验证请求参数 - 确保请求数据的有效性
        /// </summary>
        /// <param name="request">查询请求对象</param>
        /// <returns>验证结果</returns>
        private bool ValidateRequest(object request)
        {
            // 检查请求对象是否为空
            if (request == null)
            {
                return false;
            }

            // 可以根据具体的请求类型进行更详细的验证
            // 例如：检查分页参数、查询条件等

            return true;
        }

        /// <summary>
        /// 构建错误响应 - 创建统一的错误响应格式
        /// </summary>
        /// <param name="errorCode">错误代码</param>
        /// <param name="errorMessage">错误信息</param>
        /// <returns>错误响应对象</returns>
        private ApiResult<T> BuildErrorResponse<T>(EnumCode errorCode, string errorMessage)
        {
            return new ApiResult<T>
            {
                Code = errorCode,
                Message = errorMessage,
                Data = default(T)
            };
        }

        #endregion
    }
}
